{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8382978f",
   "metadata": {
    "vscode": {
     "languageId": "plaintext"
    }
   },
   "source": [
    "# LlamaParser\n",
    " \n",
    "LlamaParse는 LlamaIndex에서 개발한 문서 파싱 서비스로, 대규모 언어 모델(LLM)을 위해 특별히 설계되었습니다. 주요 특징은 다음과 같습니다:\n",
    "\n",
    "- PDF, Word, PowerPoint, Excel 등 다양한 문서 형식 지원\n",
    "- 자연어 지시를 통한 맞춤형 출력 형식 제공\n",
    "- 복잡한 표와 이미지 추출 기능\n",
    "- JSON 모드 지원\n",
    "- 외국어 지원\n",
    "\n",
    "LlamaParse는 독립형 API로 제공되며, LlamaCloud 플랫폼의 일부로도 사용 가능합니다. 이 서비스는 문서를 파싱하고 정제하여 검색 증강 생성(RAG) 등 LLM 기반 애플리케이션의 성능을 향상시키는 것을 목표로 합니다.\n",
    "\n",
    "사용자는 무료로 하루 1,000페이지를 처리할 수 있으며, 유료 플랜을 통해 추가 용량을 확보할 수 있습니다. LlamaParse는 현재 공개 베타 버전으로 제공되고 있으며, 지속적으로 기능이 확장되고 있습니다.\n",
    "\n",
    "- 링크: https://cloud.llamaindex.ai\n",
    "\n",
    "**API 키 설정**\n",
    "- API 키를 발급 후 `.env` 파일에 `LLAMA_CLOUD_API_KEY` 에 설정합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6de92eeb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 설치\n",
    "# !pip install llama-index-core llama-parse llama-index-readers-file python-dotenv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "850910e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import nest_asyncio\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "load_dotenv()\n",
    "nest_asyncio.apply()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5ff3b85",
   "metadata": {},
   "source": [
    "기본 파서 적용"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2a94cd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_parse import LlamaParse\n",
    "from llama_index.core import SimpleDirectoryReader\n",
    "\n",
    "# 파서 설정\n",
    "parser = LlamaParse(\n",
    "    result_type=\"markdown\",  # \"markdown\"과 \"text\" 사용 가능\n",
    "    num_workers=8,  # worker 수 (기본값: 4)\n",
    "    verbose=True,\n",
    "    language=\"ko\",\n",
    ")\n",
    "\n",
    "# SimpleDirectoryReader를 사용하여 파일 파싱\n",
    "file_extractor = {\".pdf\": parser}\n",
    "\n",
    "# LlamaParse로 파일 파싱\n",
    "documents = SimpleDirectoryReader(\n",
    "    input_files=[\"data/SPRI_AI_Brief_2023년12월호_F.pdf\"],\n",
    "    file_extractor=file_extractor,\n",
    ").load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f4aabfb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 페이지 수 확인\n",
    "len(documents)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a08fb03",
   "metadata": {},
   "outputs": [],
   "source": [
    "documents[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "179d4e1b",
   "metadata": {},
   "source": [
    "LlamaIndex -> LangChain Document 로 변환"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10be578a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 랭체인 도큐먼트로 변환\n",
    "docs = [doc.to_langchain_format() for doc in documents]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4db68c10",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(docs[5].page_content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "89ec141f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# metadata 출력\n",
    "docs[0].metadata"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7845a3bc",
   "metadata": {},
   "source": [
    "## MultiModal Model 로 파싱\n",
    "\n",
    "**주요 파라미터**\n",
    "\n",
    "- `use_vendor_multimodal_model`: 멀티모달 모델 사용 여부를 지정합니다. `True`로 설정하면 외부 벤더의 멀티모달 모델을 사용합니다.\n",
    "\n",
    "- `vendor_multimodal_model_name`: 사용할 멀티모달 모델의 이름을 지정합니다. 여기서는 \"openai-gpt4o\"를 사용하고 있습니다.\n",
    "\n",
    "- `vendor_multimodal_api_key`: 멀티모달 모델 API 키를 지정합니다. 환경 변수에서 OpenAI API 키를 가져옵니다.\n",
    "\n",
    "- `result_type`: 파싱 결과의 형식을 지정합니다. \"markdown\"으로 설정되어 있어 결과가 마크다운 형식으로 반환됩니다.\n",
    "\n",
    "- `language`: 파싱할 문서의 언어를 지정합니다. \"ko\"로 설정되어 한국어로 처리됩니다.\n",
    "\n",
    "- `skip_diagonal_text`: 대각선 텍스트를 건너뛸지 여부를 결정합니다.\n",
    "\n",
    "- `page_separator`: 페이지 구분자를 지정할 수 있습니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f03fc375",
   "metadata": {},
   "outputs": [],
   "source": [
    "documents = LlamaParse(\n",
    "    use_vendor_multimodal_model=True,\n",
    "    vendor_multimodal_model_name=\"openai-gpt4o\",\n",
    "    vendor_multimodal_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
    "    result_type=\"markdown\",\n",
    "    language=\"ko\",\n",
    "    # skip_diagonal_text=True,\n",
    "    # page_separator=\"\\n=================\\n\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04c986f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# parsing 된 결과\n",
    "parsed_docs = documents.load_data(file_path=\"data/SPRI_AI_Brief_2023년12월호_F.pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55bb48fe",
   "metadata": {},
   "outputs": [],
   "source": [
    "# langchain 도큐먼트로 변환\n",
    "docs = [doc.to_langchain_format() for doc in parsed_docs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbe71f55",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(docs[18].page_content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc038703",
   "metadata": {},
   "source": [
    "아래와 같이 사용자 정의 인스트럭션을 지정하는 것도 가능합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2863efda",
   "metadata": {},
   "outputs": [],
   "source": [
    "# parsing instruction 을 지정합니다.\n",
    "parsing_instruction = (\n",
    "    \"You are parsing a brief of AI Report. Please extract tables in markdown format.\"\n",
    ")\n",
    "\n",
    "# LlamaParse 설정\n",
    "parser = LlamaParse(\n",
    "    use_vendor_multimodal_model=True,\n",
    "    vendor_multimodal_model_name=\"openai-gpt4o\",\n",
    "    vendor_multimodal_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
    "    result_type=\"markdown\",\n",
    "    language=\"ko\",\n",
    "    parsing_instruction=parsing_instruction,\n",
    ")\n",
    "\n",
    "# parsing 된 결과\n",
    "parsed_docs = parser.load_data(file_path=\"data/SPRI_AI_Brief_2023년12월호_F.pdf\")\n",
    "\n",
    "# langchain 도큐먼트로 변환\n",
    "docs = [doc.to_langchain_format() for doc in parsed_docs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0d87bf2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# markdown 형식으로 추출된 테이블 확인\n",
    "print(docs[-2].page_content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py-test",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
